package bill.study.concurrency.executorframework.extension;

import java.util.Queue;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;

public class SerialExecutor implements Executor {

	final Queue<Runnable> tasks = new LinkedBlockingQueue<Runnable>();
	final Executor executor;
	Runnable active;
	
	SerialExecutor (Executor executor){
		this.executor = executor;
	}

	@Override
	public synchronized void execute(final Runnable command) {
		tasks.offer(new Runnable(){

			@Override
			public void run() {
				try{
					command.run();
				}finally{
					scheduleNext();
				}
				
			}});
		
	}
	
	protected synchronized void scheduleNext(){
		if((active = tasks.poll())!= null){
			executor.execute(active);
		}
	}

}
